{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "ename": "ModuleNotFoundError",
     "evalue": "No module named 'sklearn.linear_model.coordinate_descent'",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mModuleNotFoundError\u001b[0m                       Traceback (most recent call last)",
      "\u001b[1;32m~\\AppData\\Local\\Temp/ipykernel_3892/3830599914.py\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m      8\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0msklearn\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mpreprocessing\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mPolynomialFeatures\u001b[0m  \u001b[1;31m#多项式特征\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m      9\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0msklearn\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mpipeline\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mPipeline\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 10\u001b[1;33m \u001b[1;32mfrom\u001b[0m \u001b[0msklearn\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mlinear_model\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcoordinate_descent\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mConvergenceWarning\u001b[0m \u001b[1;31m#拦截异常的\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m     11\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0msklearn\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mmodel_selection\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mtrain_test_split\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m     12\u001b[0m \u001b[1;32mfrom\u001b[0m \u001b[0msklearn\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mpreprocessing\u001b[0m \u001b[1;32mimport\u001b[0m \u001b[0mStandardScaler\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n",
      "\u001b[1;31mModuleNotFoundError\u001b[0m: No module named 'sklearn.linear_model.coordinate_descent'"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "import matplotlib as mpl\n",
    "import  matplotlib.pyplot as plt\n",
    "import  pandas as pd\n",
    "import  warnings\n",
    "import sklearn\n",
    "from sklearn.linear_model import LinearRegression,LassoCV,RidgeCV,ElasticNetCV\n",
    "from sklearn.preprocessing import PolynomialFeatures  #多项式特征\n",
    "from sklearn.pipeline import Pipeline\n",
    "from sklearn.linear_model.coordinate_descent import ConvergenceWarning #拦截异常的\n",
    "from sklearn.model_selection import train_test_split\n",
    "from sklearn.preprocessing import StandardScaler\n",
    "from sklearn.grid_search import GridSearchCV  #从sklearn.grid_search中导入网格搜索模块GridSearchCV。\n",
    "from sklearn import  metrics  #评价指标\n",
    "\n",
    "def notEmpty(s):\n",
    "    return s !=''    #是空的话就是FLASE，不是空的话就是TRUE\n",
    "\n",
    "#设置字符集，防止中文乱码\n",
    "\n",
    "mpl.rcParams['font.sans-serif']=[u'simHei']\n",
    "mpl.rcParams['axes.unicode_minus']=False\n",
    "#拦截异常\n",
    "warnings.filterwarnings(action = 'ignore', category=ConvergenceWarning)\n",
    "\n",
    "\n",
    "# 加载数据\n",
    "names = ['CRIM','ZN', 'INDUS','CHAS','NOX','RM','AGE','DIS','RAD','TAX','PTRATIO','B','LSTAT']  #前13个和房价相关的字段，LSTAT为房价\n",
    "path = \"datas/boston_housing.data\"\n",
    "# 由于数据文件格式不统一，所以读取的时候，先按照一行一个字段属性读取数据，然后再安装每行数据进行处理\n",
    "fd = pd.read_csv(path,header=None)\n",
    "#print(fd.shape)\n",
    "data = np.empty((len(fd),14))  # len(fd)行，14列\n",
    "for i, d in enumerate(fd.values): #enumerate生成一列索引i,d为其元素\n",
    "    d = map(float,filter(notEmpty,d[0].split(' '))) #filter一个函数，一个list, 就是空的扔掉，有值的留下\n",
    "\n",
    "    #根据函数结果是否为真 ，来过滤list中的项\n",
    "    data[i]=list(d)\n",
    "\n",
    "#分割数据\n",
    "x,y = np.split(data,(13,),axis=1)  #分割前13列数据\n",
    "# print(x[0:5])\n",
    "#print(y)  由于y是个二维的，所以要用ravel拉成一维的\n",
    "y = y.ravel()  #转换格式  拉直操作\n",
    "#print(y[0:5])\n",
    "ly=len(y)\n",
    "# print(y.shape)\n",
    "print('样本数据量:%d,特征个数:%d '%x.shape)\n",
    "print('target样本数据量:%d'%y.shape[0])\n",
    "\n",
    "#Pipeline常用于并行调参\n",
    "models = [\n",
    "    Pipeline([\n",
    "            ('ss', StandardScaler()),\n",
    "            ('poly', PolynomialFeatures()),\n",
    "            ('linear', RidgeCV(alphas=np.logspace(-3,1,20)))\n",
    "        ]),\n",
    "    Pipeline([\n",
    "            ('ss', StandardScaler()),\n",
    "            ('poly', PolynomialFeatures()),\n",
    "            ('linear', LassoCV(alphas=np.logspace(-3,1,20))) #logspace 以10为底，从10的-3次方止10的0次方，中间有20步\n",
    "        ]),\n",
    "    Pipeline([\n",
    "            ('ss', StandardScaler()),\n",
    "            ('poly', PolynomialFeatures()),\n",
    "            ('linear', LinearRegression())\n",
    "        ]),\n",
    "    Pipeline([\n",
    "            ('ss', StandardScaler()),\n",
    "            ('poly', PolynomialFeatures()),\n",
    "            ('linear', ElasticNetCV(alphas=np.logspace(-3,1,20)))\n",
    "        ])\n",
    "]\n",
    "\n",
    "#参数字典，字典中的key是属性的名称，value是可选的参数列表\n",
    "parameters = {\n",
    "    \"poly__degree\": [3,2,1],\n",
    "    \"poly__interaction_only\": [True, False],#只产生交互相选TRUE，得到[0次方，X本身，Y本身，X1*Y1] ；默认选FLASE，不仅产生交互项，如X1*X1,Y1*Y1也会有\n",
    "    \"poly__include_bias\": [True, False],    #多项式幂为零的特征作为线性模型中的截距,默认为True\n",
    "    \"linear__fit_intercept\": [True, False]\n",
    "}\n",
    "\n",
    "# rf = PolynomialFeatures(2,interaction_only=True)\n",
    "# a = pd.DataFrame({\n",
    "#     'name':[1,2,3,4,5],\n",
    "#     'score':[2,3,4,4,5]\n",
    "# })\n",
    "# b=rf.fit_transform(a)\n",
    "# print(b)\n",
    "\n",
    "#数据分割\n",
    "x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=0)\n",
    "\n",
    "#Lasso和Ridge模型比较运行图表展示\n",
    "titles = ['Ridge','Lasso','LinearRegression','ElasticNet']\n",
    "colors = ['g-','b-','y-','c-']\n",
    "plt.figure(figsize=(16,8), facecolor='w')\n",
    "ln_x_test = range(len(x_test))\n",
    "\n",
    "plt.plot(ln_x_test, y_test,'r-',lw=2,label=u'真实值')\n",
    "for t in range(4):\n",
    "    #获取模型并设置参数\n",
    "    #GridSearchCV: 进行交叉验证，选择出最优的参数值出来\n",
    "    #第一个输入参数：进行参数选择的模型，\n",
    "    #param_grid： 用于进行模型选择的参数字段，要求是字典类型；cv: 进行几折交叉验证\n",
    "\n",
    "    model = GridSearchCV(models[t], param_grid=parameters, cv=5, n_jobs=1) #五折交叉验证\n",
    "    #模型训练-网格搜索\n",
    "    model.fit(x_train, y_train)\n",
    "    #模型效果值获取（最优参数）\n",
    "    print('%s算法：最优参数：'%titles[t],model.best_params_)\n",
    "    print('%s算法：R值=%.3f'%(titles[t],model.best_score_))\n",
    "    #模型预测\n",
    "    y_predict=model.predict(x_test)\n",
    "    #画图\n",
    "    plt.plot(ln_x_test,y_predict,colors[t],lw=2,label=u'%s算法估计值，$R^2$=%.3f'%(titles[t],model.best_score_))\n",
    "#图形显示\n",
    "plt.legend(loc='lower right')\n",
    "plt.grid(True)\n",
    "plt.title(u'波士顿房屋价格预测')\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
